Skip to content

process.env.NODE_ENV 的理解

什么是 process.env.NODE_ENV

process.env.NODE_ENV应该是我们最熟悉的环境变量了,它经常出现在使用框架或者类库的时候,被用来区分不同的环境(开发,测试,生产等),以便我们进行相对应的项目配置,比如是否开启 sourceMap,api 地址切换等。那为什么process.env.NODE_ENV能用来区分环境呢?它是如何来的?

先来看一下processprocess.env的官方解释:

  • process

process 对象是一个 global (全局变量),提供有关信息,控制当前 Node.js 进程。作为一个对象,它对于 Node.js 应用程序始终是可用的,故无需使用 require()

  • process.env

process.env属性返回一个包含用户环境信息的对象。

在 node 环境中,当我们打印process.env时,发现它并没有NODE_ENV这一个属性。实际上,process.env.NODE_ENV是在 package.json 的scripts命令中注入的,也就是NODE_ENV并不是 node 自带的,而是由用户定义的,至于为什么叫NODE_ENV,应该是约定成俗的吧。

json
{
  "scripts": {
    "dev": "NODE_ENV=development webpack --config webpack.dev.config.js"
  }
}

可以看到NODE_ENV被赋值为development,当执行npm run dev时,我们就可以在 webpack.dev.config.js脚本中以及它所引入的脚本中访问到process.env.NODE_ENV,而无法在其它脚本中访问。

如何在其他脚本中访问

前面提到,在scripts命令中注入的NODE_ENV只能被 webpack 的构建脚本访问,而被 webpack 打包的源码中是无法访问到的,此时可以借助 webpack 的 DefinePlugin 插件,创建全局变量。

js
const webpack = require("webpack");
module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": '"development"',
    }),
  ],
};

当然DefinePlugin不仅仅可以定义process.env.NODE_ENV,你也可以根据自己的需要定义其他的全局变量。定义完成之后,就可以在项目代码中直接使用了。

跨平台的 cross-env

在 window 平台下直接设置NODE_ENV =XXX是会报错的,cross-env 能够提供一个设置环境变量的scripts,这样我们就能够以 unix 方式设置环境变量,然后在 windows 上也能够兼容。

  • 安装cross-env

    shell
    npm install cross-env --save
  • NODE_ENV=XXX前面添加cross-env

    json
    "scripts": {
      "dev": "cross-env NODE_ENV=development webpack-dev-server"
    }

使用. env 文件

如果需要配置的环境变量太多,全部设置在scripts命令中既不美观也不容易维护,此时将环境变量配置在.env文件中,然后使用dotenv插件来加载.env配置文件。

  • 安装dotenv

    shell
    npm install dotenv --save
  • 创建.env文件

    ini
    NODE_ENV = development
    # 这是注释
    API_URL = https://abc.com
  • 在程序中引入和配置dotenv。在 config 函数中可以配置.env 文件的路径。具体参考dotenv 文档

    js
    require("dotenv").config();

这样就可以在程序中使用环境变量了。

在实际项目中,我们一般还是在scripts命令中设置NODE_ENV,然后通过不同的NODE_ENV来加载不同的.env文件。

举个例子:

有一个项目,简单的项目结构如下:

txt
├── env
   ├── .env.dev
   ├── .env.test
   ├── .env.pre
   └── .env.prd
├── webpack.config.js

.env.***文件中配置了每个环境对应的变量,例如:

ini
# .env.test 文件
API_URL = https://abc-test.com

# .env.pre 文件
API_URL = https://abc-pre.com

# .env.prd 文件
API_URL = https://abc.com

webpack.config.js加载env配置:

js
require("dotenv").config({
  path: path.resolve(__dirname, "./env/.env." + process.env.NODE_ENV),
});

最后别忘了还要在scripts命令中设置NODE_ENV

ini
# dev
cross-env NODE_ENV=dev

# test
cross-env NODE_ENV=test

# pre
cross-env NODE_ENV=pre

# prd
cross-env NODE_ENV=prd

Vue cli 也可以加载.env文件,详情可查看:Vue cli-环境变量和模式

扩展

因为 dotenv 是直接将 .env 文件加到 process.env 里的,那为了区分到底是用户的变量还是原来就有的变量,就不得不限制前缀,这就是为什么在vue-cli、viteenv里必须写VUE_APP_、VITE_前缀开头的了



⭐️⭐️⭐️ 好啦!!!本文章到这里就结束啦。⭐️⭐️⭐️

✿✿ ヽ(°▽°)ノ ✿

撒花 🌸🌸🌸🌸🌸🌸

上次更新于: